package com.mobile.framework.tag;

import com.mobile.framework.util.Constants;
import com.mobile.framework.util.PageList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.taglib.TagUtils;
import org.apache.struts.taglib.html.BaseTag;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

/**
 * Standard page navigator. usage: <app:page name="users"
 * searchForm="searchUserForm" showJumpBox="false" showRowSelect="true"
 * rowNumber="5,10,30">
 * name设置数据集(必须是PageList)的名称,searchForm设置相关查询表单的名称,如果设置该属性将自动生成相关javascript代码
 * showJumpBox 决定是否显示页面跳转框,showRowSelect决定是否显示每页记录数选择框,rowNumber决定可选的每页记录数
 * 除name属性,其他都是可选属性,缺省控制由config.property文件中page.jump.disable,page.rows配置决定
 */
public class PageTag extends BaseTag {

    private static String LABEL_FIRST_PAGE = "第一页";

    private static String LABEL_PREVIOUS_PAGE = "上一页";

    private static String LABEL_NEXT_PAGE = "下一页";

    private static String LABEL_LAST_PAGE = "最后一页";

    private static String LABEL_GO_PAGE = "跳转";

    private static String LABEL_ROWS_PER_PAGE = "每页记录数";

    private static String[] LABEL_PAGE_SUMMARY = {"第{", "}/{", "}页 共{", "}条记录"};

    private static String ERROR_PAGE_NUMBER = "输入的页码无效";

    private static String COMMON_BUNDLE_KEY = "common";

    private final static String TEMPLATE_PAGE = "/PageTag.html";

    private Log log = LogFactory.getLog(this.getClass());

    // ----------------------------------------------------- Instance Variables

    /**
     * Bean name of the recordset, you need to set this value in your action
     * class and give this value in your jsp file
     */
    private String space = " ";

    protected String name;// 数据集对象名

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    protected String searchForm = null;// 搜索表单名

    public String getSearchForm() {
        return searchForm;
    }

    public void setSearchForm(String searchForm) {
        this.searchForm = searchForm;
    }

    protected String showJumpBox = null;// 是否显示跳转框

    public String getShowJumpBox() {
        return showJumpBox;
    }

    public void setShowJumpBox(String showJumpBox) {
        this.showJumpBox = showJumpBox;
    }

    protected String showRowSelect = "false";// 是否显示每页数选择框

    public String getShowRowSelect() {
        return showRowSelect;
    }

    public void setShowRowSelect(String showRowSelect) {
        this.showRowSelect = showRowSelect;
    }

    protected String rowNumber = null;// 可选的每页记录数

    public String getRowNumber() {
        return rowNumber;
    }

    public void setRowNumber(String rowNum) {
        this.rowNumber = rowNum;
    }

    private final static   StringBuffer templatePageS ;

    static {
        try {
            templatePageS = (new PageTag()).readFile(TEMPLATE_PAGE);
        } catch (IOException e) {
            e.printStackTrace();
            throw new IllegalArgumentException("分页页面" + TEMPLATE_PAGE + "不存在");
        }
    }

    private StringBuffer readFile(String filePath) throws IOException {
        StringBuffer _sb = new StringBuffer();
        InputStream in = PageTag.class.getResourceAsStream(filePath);
        BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
        String temp = "";
        while ((temp = br.readLine()) != null) {
            _sb.append(temp);
            _sb.append("\n");
        }

        return _sb;
    }

    /**
     * Process the start of this tag. Overwirte super class's method. Do nothing
     * instead of render base element.
     *
     * @throws JspException if a JSP exception has occurred
     */
    @Override
    public int doStartTag() throws JspException {
        return EVAL_BODY_INCLUDE;
    }

    /**
     * Render an input element for this tag.
     *
     * @throws JspException if a JSP exception has occurred
     */
    @Override
    public int doEndTag() throws JspException {

//        try {
//            templatePageS = (new PageTag()).readFile(TEMPLATE_PAGE);
//        } catch (IOException e) {
//            e.printStackTrace();
//            throw new IllegalArgumentException("分页页面" + TEMPLATE_PAGE + "不存在");
//        }
        // Create an appropriate "input" element based on our parameters
        StringBuffer results = new StringBuffer(templatePageS);
        Object bean = TagUtils.getInstance().lookup(pageContext, name, null);
        if (name != null && bean == null) {
            // throw new JspException(messages.getMessage("getter.bean", name));
            bean = new PageList();
        }

        // 是否显示分页跳转和记录数选择框(缺省值)
//		boolean showJumpSelect = "true".equals("false") ? false : true;

        try {
            PageList p = (PageList) bean;

            //处理分页信息
            showPageInfo(results, p);
            //显示rowsPerPage的选择框
            showRowSelect(results);
            //加载javascript函数
            showJavaScript(results, searchForm, p.getPageCount());


        } catch (Exception e) {
            log.error("doEndTag() error:" + e, e);
            throw new JspException(e.getMessage(), e);
        }

        // Render this element to our response
        TagUtils.getInstance().write(pageContext, results.toString());

        // Continue evaluating this page
        return (EVAL_PAGE);

    }

    // 显示分页信息和链接
    private void showPageInfo(StringBuffer results, PageList p)
            throws JspException {

        int currentPage = p.getCurrentPage();
        int pageCount = p.getPageCount();
        int totalRowCount = p.getTotalRowCount();

        // 合计页数
        parseTags(results, "###currentPage###", null, String.valueOf(currentPage));
        parseTags(results, "###pageCount###", null, String.valueOf(pageCount));
        parseTags(results, "###totalRowCount###", null, String.valueOf(totalRowCount));

        // 第一页
        if (pageCount > 1 && currentPage > 1) {
            parseTags(results, "<!--startFirstPageHref-->", null, "");
            parseTags(results, "<!--endFirstPageHref-->", null, "");
            parseTags(results, "<!--startFirstPageSpan-->", "<!--endFirstPageSpan-->", "");
        } else {
            parseTags(results, "<!--startFirstPageHref-->", "<!--endFirstPageHref-->", "");
            parseTags(results, "<!--startFirstPageSpan-->", null, "");
            parseTags(results, "<!--endFirstPageSpan-->", null, "");

        }

        // 上一页
        if (currentPage > 1) {
            parseTags(results, "<!--startPreviousPageHref-->", null, "");
            parseTags(results, "<!--endPreviousPageHref-->", null, "");
            parseTags(results, "<!--startPreviousPageSpan-->", "<!--endPreviousPageSpan-->", "");
            parseTags(results, "###previousPage###", null, String.valueOf(currentPage - 1));
        } else {
            parseTags(results, "<!--startPreviousPageHref-->", "<!--endPreviousPageHref-->", "");
            parseTags(results, "<!--startPreviousPageSpan-->", null, "");
            parseTags(results, "<!--endPreviousPageSpan-->", null, "");
        }

        // 下一页
        if (currentPage < pageCount) {
            parseTags(results, "<!--startNextPageHref-->", null, "");
            parseTags(results, "<!--endNextPageHref-->", null, "");
            parseTags(results, "<!--startNextPageSpan-->", "<!--endNextPageSpan-->", "");
            parseTags(results, "###nextPage###", null, String.valueOf(currentPage + 1));
        } else {
            parseTags(results, "<!--startPreviousPageHref-->", "<!--endPreviousPageHref-->", "");
            parseTags(results, "<!--startPreviousPageSpan-->", null, "");
            parseTags(results, "<!--endPreviousPageSpan-->", null, "");
        }

        // 最后一页
        if (currentPage < pageCount) {
            parseTags(results, "<!--startLastPageHref-->", null, "");
            parseTags(results, "<!--endLastPageHref-->", null, "");
            parseTags(results, "<!--startLastPageSpan-->", "<!--endLastPageSpan-->", "");
            parseTags(results, "###lastPage###", null, String.valueOf(pageCount));
        } else {
            parseTags(results, "<!--startNextPageHref-->", "<!--endNextPageHref-->", "");
            parseTags(results, "<!--startNextPageSpan-->", null, "");
            parseTags(results, "<!--endNextPageSpan-->", null, "");
            parseTags(results, "<!--startLastPageHref-->", "<!--endLastPageHref-->", "");
            parseTags(results, "<!--startLastPageSpan-->", null, "");
            parseTags(results, "<!--endLastPageSpan-->", null, "");
        }

        //显示跳转页码框
         if (null != showJumpBox && "true".equals(showJumpBox)) {
            parseTags(results, "<!--startJumpPage-->", null, "");
            parseTags(results, "<!--endJumpPage-->", null, "");
        } else {
            parseTags(results, "<!--startJumpPage-->", "<!--endJumpPage-->", "");
        }
    }



    // 显示每页记录数选择框
    private void showRowSelect(StringBuffer results) throws JspException {
        // 每页记录数选择框
        if (null != showRowSelect && "true".equals(showRowSelect)) {
            //过滤 results
            parseTags(results, "<!--startRowsPerPage-->", null, "");
            parseTags(results, "<!--endRowsPerPage-->", null, "");

            HttpServletRequest req = (HttpServletRequest) pageContext.getRequest();
            String curRows = req.getParameter("rowsPerPage");
            if (null == curRows || "".equals(curRows)) {
                curRows = Constants.ROWS_PER_PAGE;
            }
            // 可选每页记录数的值
            String rowsValueList = this.rowNumber;
            if (null == rowsValueList || "".equals(rowsValueList)) {
                // 从配置文件取可选记录数
                rowsValueList = "10,15,20,30,60,100";
            }
            StringTokenizer st = new StringTokenizer(rowsValueList, ",");
            StringBuffer options = new StringBuffer("");
            // 生成下拉框
            while (st.hasMoreTokens()) {
                String row = st.nextToken();
                options.append("<option value=\"" + row + "\"");
                if (row.equals(curRows)) {
                    options.append(" selected ");
                }
                options.append(">" + row + "</option>");
            }
            parseTags(results, "###rowNumber###", null, options.toString());
        } else {
            parseTags(results, "<!--startRowsPerPage-->", "<!--endRowsPerPage-->", "");
        }
    }

    // 显示javascript
    private void showJavaScript(StringBuffer results, String formName,
                                int maxRows) throws JspException {

        if (null != searchForm && !"".equals(searchForm)) {
            parseTags(results, "###searchForm###", null, searchForm);
            parseTags(results, "###maxRows###", null, String.valueOf(maxRows));

        }else{
            parseTags(results, "<!--startJavascript-->", "<!--endJavascript-->", "");
        }
    }

    private String getMessage(String key) throws JspException {
        // return TagUtils.getInstance().message(pageContext, null,
        // null, key);
        return key;
    }

    /**
     * @param key  key 资源名数组
     * @param args args 参数值数组
     * @throws JspException if a JSP exception has occurred
     */
    private String getMessage(String[] key, Object[] args) throws JspException {
        StringBuffer value = new StringBuffer();
        int length = 0;
        Object[] max = null;
        if (key.length <= args.length) {
            length = key.length;
            max = args;
        } else {
            length = args.length;
            max = key;
        }
        for (int i = 0; i < length; i++) {
            value.append(key[i]).append(args[i]);
        }
        for (int j = length; j < max.length; j++) {
            value.append(max[j]);
        }
        return value.toString();
    }

    private void parseTags(StringBuffer sb, String from, String to, String replace) {
        if (null == from || null == sb) {
            throw new IllegalArgumentException("Miss arguments: from || sb");
        }
        if (null == to) {
            int indexFrom = sb.indexOf(from);
            if(indexFrom != -1){
                //此处仅处理第一个匹配项
                sb.replace(indexFrom, indexFrom + from.length(), replace);
            }
        } else {
            int indexFrom = sb.indexOf(from);
            int indexTo = sb.indexOf(to);
            if(indexFrom != -1)
            //此处仅处理第一个匹配项
            sb.replace(indexFrom, indexTo + to.length(), replace);
        }
    }
}